# coding: utf-8

from sqlalchemy.sql import text, or_

from app.extensions import db
from app.models import BaseModel, get_today_begin_timestamp, get_timestamp
from app.op.models import User, Audio
from app.op.constant import OperateResult
from app.ccws.models import OutBoundRecord
from app.seven_moor.constant import (
    AnswerState, CallState, CallType,
)
from common.seven_moor.constant import (
    OUTBOUND_SERVICE_NO, BRIDGE_SERVICE_NO
)


class SevenMoorRecord(BaseModel):
    """
    add by zhouhl 2018-01-10
    七陌通话记录
    """
    __tablename__ = 'seven_moor_records'

    filter_dict = {
        'transform_result': (),
        'call_type': (),
        'answer_state': (),
    }

    # 主叫号码
    call_no = db.Column(db.String(16), index=True)
    # 被叫号码
    called_no = db.Column(db.String(16), index=True)
    # 通话记录ID,CallSheetID 是这条通话记录再DB中的唯一id
    call_sheet_id = db.Column(db.String(40), index=True)
    # 通话类型。dialout外呼通话,normal普通来电,transfer转接电话,dialTransfer外呼转接
    call_type = db.Column(db.String(64))
    # 通话振铃时间
    ring = db.Column(db.DateTime(), nullable=True)
    # 通话接通时间
    begin = db.Column(db.DateTime(), nullable=True)
    # 通话结束时间
    end = db.Column(db.DateTime(), nullable=True)
    # 来电进入技能组时间
    queue_time = db.Column(db.DateTime(), nullable=True)
    # 处理坐席的工号
    agent = db.Column(db.String(16))
    # 处理坐席的姓名
    agent_name = db.Column(db.String(64))
    # 通话进入的技能组名称
    queue = db.Column(db.String(16))
    # 接听状态：dealing（已接）,notDeal（振铃未接听）,leak（ivr放弃）,queueLeak（排队放弃）,blackList（黑名单）,voicemail（留言）
    answer_state = db.Column(db.String(16))
    # 事件状态：Ring, Ringing, Link, Hangup(Unlink也当成Hangup处理)
    call_state = db.Column(db.String(16))
    # 通过接口调用时,该字段会保存请求的actionID,其它情况下该字段为空
    action_id = db.Column(db.String(32))
    # 通过调用webcall接口,该字段会保存请求的actionID,其它情况下该字段为空
    webcall_action_id = db.Column(db.String(32), index=True)
    # 通话录音文件名：用户要访问录音时,在该文件名前面加上服务路径即可,如：FileServer/RecordFile
    record_file = db.Column(db.String(256))
    # 通过FileServer中指定的地址加上RecordFile的值可以获取录音
    file_server = db.Column(db.String(128))
    # 目标号码的省,呼入为来电号码,呼出为去电号码
    province = db.Column(db.String(64))
    # 目标号码的市,呼入为来电号码,呼出为去电号码
    district = db.Column(db.String(64))
    # 通话ID,通话连接的在系统中的唯一标识
    call_id = db.Column(db.String(32))
    # 通话在系统中选择的按键菜单,10004@0。格式为：按键菜单的节点编号@选择的菜>单按键。如果为多级菜单则为：10004@0-10005@1。
    ivr_key = db.Column(db.String(512))
    # 转化结果
    transform_result = db.Column(
        db.Integer, nullable=False, server_default=text("'0'"), default=0)
    # 延后理由
    delay_reason = db.Column(db.Text, default='')
    # 操作时间(处理时间-拨打时间, 单位为秒)
    handle_time = db.Column(db.Integer, default=0)
    demand_id = db.Column(
        db.Integer, nullable=False, server_default=text("'0'"), default=0)
    is_bid_queue = db.Column(db.Boolean, default=False, server_default=text("FALSE"))
    # 不创建订单(放弃订单)理由
    not_create_reason = db.Column(db.Text, default='')

    # add by zhouhl 2018-03-09
    # 是否使用虚拟号
    use_virtual_number = db.Column(db.Boolean, default=False, server_default=text("FALSE"))
    # 客户的真实号码，不管是呼入还是呼出
    customer_real_number = db.Column(db.String(128), server_default=text("''"), default='')

    @classmethod
    def get_today_records(cls):
        """
        add by zhouhl 2018-01-15
        取当天的通话记录，主要供客服动态刷新使用
        """
        return cls.query.filter(
            cls.created_at >= get_today_begin_timestamp(),
            cls.called_no != BRIDGE_SERVICE_NO,
            cls.is_bid_queue.is_(False)
        ).order_by(
            cls.id.desc()
        )

    @property
    def handle_time_display(self):
        if self.handle_time:
            return '{}分{}秒'.format(self.handle_time // 60, self.handle_time % 60)
        return 0

    @property
    def call_type_display(self):
        """
        add by zhouhl 2018-01-15
        发起方式
        """
        if self.call_type == CallType.NORMAL.value \
            and self.called_no in (OUTBOUND_SERVICE_NO, BRIDGE_SERVICE_NO):
            return self.call_reason_display
        return CallType(self.call_type).display

    @property
    def call_reason_display(self):
        """
        add by zhouhl 2018-01-15
        外呼原因
        """
        outbound = OutBoundRecord.get_by_args(
            webcall_action_id=self.webcall_action_id
        )
        return outbound.call_reason_display if outbound else '--'

    @property
    def answer_state_display(self):
        """
        add by zhouhl 2018-01-15
        接听状态
        """
        if self.answer_state == AnswerState.DEALING.value:
            answer_second = (self.end - self.begin).seconds \
                if (self.begin and self.end) else 0
            result = '{}分{}秒'.format(answer_second // 60, answer_second % 60)
        else:
            result = AnswerState(self.answer_state).display
        return result

    @property
    def call_state_display(self):
        """
        add by zhouhl 2018-01-15
        事件状态
        """
        return CallState.get(self.call_state, '未知')

    @property
    def customer_number(self):
        """
        add by zhouhl 2018-01-15
        根据呼入呼出返回客户号码
        """
        if self.use_virtual_number:
            return self.customer_real_number
        elif self.call_type == CallType.DIALOUT.value:
            return self.called_no
        else:
            return self.call_no

    @property
    def customer_nickname(self):
        """
        add by zhouhl 2018-01-15
        返回客户昵称
        """
        mobile = self.customer_number
        user = User.get_by_args(
            mobile=mobile,
            deleted_at=0
        )
        return user.nickname if user else '万屏汇客户'

    @property
    def customer_id(self):
        """
        add by zhouhl 2018-01-15
        返回客户ID
        """
        mobile = self.customer_number
        user = User.get_by_args(
            mobile=mobile,
            deleted_at=0
        )
        return user.id if user else None

    @property
    def record_file_url(self):
        """
        add by zhouh 2018-01-15
        返回录音文件url
        """
        return self.file_server + '/' + self.record_file

    @property
    def audio_url(self):
        """
        add by zhouhl 2018-06-05
        返回本地服务器录音文件url
        """
        audio = Audio.get_by_args(seven_moor_call_id=self.call_id)
        return audio.audio_url if audio else None

    @property
    def transform_result_display(self):
        """
        add by zhouh 2018-01-16
        转化结果
        """
        return OperateResult(self.transform_result).display

    @property
    def extra_info(self):
        """
        额外信息:
        不创建, 放弃订单: 返回原因
        :return:
        """
        if self.transform_result in (
            OperateResult.INVALID_DEMAND.value, OperateResult.INVALID_OP.value,
        ):
            return self.not_create_reason
        if self.transform_result == OperateResult.DELAY_OP.value:
            return self.delay_reason
        return ''

    @classmethod
    def complete(cls, uid, operate_result, delay_reason='', demand_id=0, not_create_reason=''):
        """
        created by chenhj at 22/01/2018
        取最后一条未处理的数据
        """
        user = User.get_by_id(uid)
        # NOTE by zhouhl 2018-07-30 可能会有幽灵用户（手机号为空）提交项目，所以判断一下 user.mobile 非空
        if user.mobile:
            # 延后发布(已发布)使用demand_id去查询数据, 否则会出现替人发布时找不到数据的情况
            if operate_result == OperateResult.DELAY_PUBLISH_DONE.value and demand_id:
                moor_rec = cls.query.filter(
                    cls.demand_id == demand_id,
                    cls.transform_result == OperateResult.DELAY_PUBLISH.value
                ).first()
            else:
                moor_rec = cls.query.filter(
                    or_(
                        cls.called_no == user.mobile,
                        cls.call_no == user.mobile,
                        cls.customer_real_number == user.mobile,
                    ),
                    cls.transform_result == OperateResult.NA.value
                ).order_by(
                    cls.id.desc()
                ).first()
            if moor_rec:
                moor_rec.transform_result = operate_result
                moor_rec.handle_time = get_timestamp() - moor_rec.created_at
                moor_rec.delay_reason = delay_reason
                moor_rec.demand_id = demand_id
                moor_rec.not_create_reason = not_create_reason
            # 把其他的数据设置成已被处理
            records = cls.query.filter(
                or_(
                    cls.called_no == user.mobile,
                    cls.call_no == user.mobile,
                    cls.customer_real_number == user.mobile,
                ),
                cls.transform_result == OperateResult.NA.value
            )
            for each in records:
                each.transform_result = OperateResult.DONE_BY_OTHER.value
